package hr.fer.zpr.nmbp.project2.dao;

import hr.fer.zpr.nmbp.project2.dao.exceptions.PrimaryKeyConstraintException;
import hr.fer.zpr.nmbp.project2.model.Dijagnoza;
import hr.fer.zpr.nmbp.project2.model.Karton;
import hr.fer.zpr.nmbp.project2.model.Lijecnik;
import hr.fer.zpr.nmbp.project2.model.Pacijent;

import java.util.List;
import java.util.Properties;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.exception.ConstraintViolationException;

public class PacijentDAO {

	private Session session;

    public PacijentDAO(Session session) {
        this.session = session;
    }
    
	public void save(Pacijent pacijent) {
		if(pacijent.getMbo() == null || pacijent.getMbo().isEmpty()){
			throw new PrimaryKeyConstraintException("MBO pacijenta ne smije biti NULL");
		}
		
		Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.saveOrUpdate(pacijent);
            pacijent.getKarton().setPacijentMbo(pacijent.getMbo());
            session.save(pacijent.getKarton());
            tx.commit();
        } catch (ConstraintViolationException e) {
            if (tx != null) tx.rollback();
            throw new PrimaryKeyConstraintException("MBO pacijenta već postoji u bazi podataka");
        }
	}

	public void delete(Pacijent pacijent) {		
		Transaction tx = null;
        try {
            tx = session.beginTransaction();
            
            Lijecnik lijecnik = pacijent.getLijecnik();
            if (lijecnik != null) {	
                lijecnik.getPacijenti().remove(pacijent);
                session.merge(lijecnik);
            }
            
            Karton karton = pacijent.getKarton();
            List<Dijagnoza> dijagnoze = karton.getDijagnoze();
            for (Dijagnoza d : dijagnoze) {
                session.delete(d);
            }
            session.delete(karton);
            
            session.delete(pacijent);
            tx.commit();
        } catch (Exception e) {
            if (tx != null) tx.rollback();
            e.printStackTrace();
            throw new RuntimeException(e);
        }
	}

    
	public List<Pacijent> load(Pacijent pacijentPrototype) {
		Properties prop = new Properties();
        StringBuilder sb = new StringBuilder();
        sb.append("select p from Pacijent as p");
        if (pacijentPrototype.getMbo() != null) {
            sb.append(" where p.mbo = :mbo");
            prop.put("mbo", pacijentPrototype.getMbo());
        }
                                        
        return (List<Pacijent>) session.createQuery(sb.toString()).setProperties(prop).list();
	}

	public List<Pacijent> loadAll() {
		return (List<Pacijent>) session.createQuery("select p from Pacijent as p").list();
	}
}
